--
-- Author: mengjie0718@163.com
-- Date: 2014-12-23 11:18:32
--
local UpdateApp = {}
local XmlUtil = require("script.base.util.XmlUtil")
UpdateApp.__cname = "UpdateApp"
UpdateApp.__index = UpdateApp
UpdateApp.__ctype = 2
local size=32
local sharedDirector = cc.Director:getInstance()
local sharedFileUtils = cc.FileUtils:getInstance()
local updater = require("script.update.updater")
local HOSTSINDEX = 1
function UpdateApp.new(...)
    local instance = setmetatable({}, UpdateApp)
    instance.class = UpdateApp
    instance:ctor(...)
    return instance
end

function UpdateApp:ctor(appName, packageRoot)
    self.name = appName
    self.packageRoot = packageRoot or appName
   
    -- set global app
    _G[self.name] = self
end
function UpdateApp:isHostNameReachable(hostname)
    if type(hostname) ~= "string" then
        print(string.format("network.isHostNameReachable() - invalid hostname %s", tostring(hostname)))
        return false
    end
    return CCNetwork:isHostNameReachable(hostname)
end
function UpdateApp:run(checkNewUpdatePackage)
    require("script.base.packageDefine")
    -- cc.PLATFORM_OS_IPHONE  = 4
    -- cc.PLATFORM_OS_IPAD    = 5
    if cc.Application:getInstance():getTargetPlatform() == 4 or cc.Application:getInstance():getTargetPlatform() == 5 then
        local l = string.pack("l", 0xFFFFFFFFFFFF)
        if #l >= 8 then
            size=64
        end
    end
    if not updater.exists(DOWNLOAD_PATH.."config/config.txt") then
        local configPath = cc.FileUtils:getInstance():fullPathForFilename("config/config.txt")
        if configPath~=nil and configPath~="" and updater.exists(configPath) then
            updater.checkDirOK(DOWNLOAD_PATH)
            updater.saveFile(cc.HelperFunc:getFileData(configPath),"config/config.txt")
        end
    end
    self.us = nil
    self:runUpdateScene(function()
        self:runRootScene()
    end)
    updater.performWithDelayGlobal= self.us.performWithDelay
    HOSTSINDEX = 1
    if cc.Network:isInternetConnectionAvailable() then
        self.us.performWithDelay(function()
           self:runRootScene()
        end, 1/30)  
    else
        UpdateApp.showAlert("网络错误", "请检查网络连接！确定联网后重启运行游戏", "确定",function()
            os.exit()
        end)
    end
end
-- 循环加载 arealist 直到加载成功
function UpdateApp:initAreaList()
    if HOSTSINDEX>#HOSTS then
        HOSTSINDEX = 1
    end
    local progress = 0
    cc.HTTPRequest:createWithUrl(function(event)
        local request =  event.request
        if "failed" == event.name then
            request:cancel()
            self.us.performWithDelay(function()
                self:initAreaList() 
            end, 1/30)  
        elseif "progress" ==  event.name then
            progress=progress+1
            if progress>100 then
                request:cancel()
                self.us.performWithDelay(function()
                    self:initAreaList() 
                end, 1/30)  
            end
        elseif event.name == "completed" then
            local code = request:getResponseStatusCode()
            if code == 200 then
                local response = request:getResponseString()
                if pcall(function()
                    response = XmlUtil.collect(response)
                end) then
                    for k,v in pairs(response) do
                        if "table"==type(v) then
                            if "areas"==v.label then
                                AREA_LIST = v
                            elseif "resources"==v.label then
                                RESOURCE = v
                            end
                        end
                    end
                    if IS_DOWNLOAD_PACKAGE and RESOURCE then
                        self:checkUpdate()
                        return
                    elseif AREA_LIST then
                        self:runRootScene()
                        return
                    end
                end
            end
            self.us.performWithDelay(function()
                self:initAreaList() 
            end, 1/30)  
        elseif request:getErrorCode()~=0 then
            self.us.performWithDelay(function()
                self:initAreaList() 
            end, 1/30) 
        end
    end, HOSTS[HOSTSINDEX]..AREA_LIST_URL, cc.kCCHTTPRequestMethodGET):start()
    print(string.format("加载%s%s", HOSTS[HOSTSINDEX],AREA_LIST_URL))
    HOSTSINDEX=HOSTSINDEX+1
    
end

function UpdateApp:checkUpdate()
    if IS_DOWNLOAD_PACKAGE and RESOURCE then
        local resversion = RESOURCE.xarg.resversion
        local appversion = RESOURCE.xarg.appversion
        if AppVersion == appversion then
            local sharedUserDefault = cc.UserDefault:getInstance()
            local localResVersion =  sharedUserDefault:getStringForKey("resversion",APPResVersion)
            -- 0 未下载  1 需要下载  2 已经下载
            local SecondRes = sharedUserDefault:getStringForKey("SecondRes")
            print(resversion,localResVersion)
            APPResVersion=localResVersion
            if resversion~=localResVersion then
                print( "升级资源包")
                updater.update(self.us._updateHandler)
            elseif SecondRes == "1" then
                print( "升级第二资源包")
                updater.updateSecond(self.us._updateHandler)
            else
                print( "进入游戏")
                self:runRootScene()
            end
        else
            UpdateApp.showAlert("游戏更新", "请重新下载并安装最新版本！", "下载游戏",function()
                cc.Native:openURL("http://www.pgyer.com/sgqyAll")
                os.exit()
            end)
        end
    else
        self:runRootScene()
    end
end

-- Remove update package, load new update package and run it.
function UpdateApp:updateSelf(newUpdatePackage)
    print("UpdateApp.updateSelf ", newUpdatePackage)
    local updatePackage = {
        "script.update.UpdateApp",
        "script.update.updater",
        "script.update.updateScene",
        "script.base.packageDefine",
    }
    
    for __,v in ipairs(updatePackage) do
        package.preload[v] = nil
        package.loaded[v] = nil
    end
    
    _G[self.name] = nil
    cc.LuaLoadChunksFromZIP(newUpdatePackage)
    
    require("script.update.UpdateApp").new(self.name):run(false)
    
end

-- Show a scene for update.
function UpdateApp:runUpdateScene(handler)
    self.us = require("script.update.updateScene").addListener(handler)
    self:enterScene(self.us)
end

-- Load all of packages(except update package, it is not in finalRes.lib)
-- and run root app.
function UpdateApp:runRootScene()
    if not self.inited then
        self.inited = true
        if size>32 then
            if updater.exists("framework64.zip") then
                cc.LuaLoadChunksFromZIP("framework64.zip")
            end
            if updater.exists("game64.zip") then
                cc.LuaLoadChunksFromZIP("game64.zip")
            end
        else
            if updater.exists("framework.zip") then
                cc.LuaLoadChunksFromZIP("framework.zip")
            end
            if updater.exists("game.zip") then
                cc.LuaLoadChunksFromZIP("game.zip")
            end
        end
        if not self.us.videoPlayer then
            self.us.performWithDelay(function()
                require("script.scene.GameApp").new():run()
            end, 1/30)
        else
            self.us.onVideoEnd = function()
                 self.us.performWithDelay(function()
                    require("script.scene.GameApp").new():run()
                end, 1/30)
            end
        end
        
    end
end


function UpdateApp:exit()
    sharedDirector:endToLua()
    os.exit()
end

function UpdateApp:enterScene(__scene)
    if sharedDirector:getRunningScene() then
        sharedDirector:replaceScene(__scene)
    else
        sharedDirector:runWithScene(__scene)
    end
end
function UpdateApp.showAlert(title, message, buttonLabels, listener)
    if type(buttonLabels) ~= "table" then
        buttonLabels = {tostring(buttonLabels)}
    else
        table.map(buttonLabels, function(v) return tostring(v) end)
    end
    
    if cc.Application:getInstance():getTargetPlatform() == 3 then
        local tempListner = function(event)
            if listener then listener(event) end
        end
        LuaJavaBridge.callStaticMethod("org/cocos2dx/utils/PSNative", "createAlert", {title, message, buttonLabels, tempListner}, "(Ljava/lang/String;Ljava/lang/String;Ljava/util/Vector;I)V");
    else
        local defaultLabel = ""
        if #buttonLabels > 0 then
            defaultLabel = buttonLabels[1]
            table.remove(buttonLabels, 1)
        end

        cc.Native:createAlert(title, message, defaultLabel)
        for i, label in ipairs(buttonLabels) do
            cc.Native:addAlertButton(label)
        end

        if type(listener) ~= "function" then
            listener = function() end
        end

        cc.Native:showAlert(listener)
    end
end
return UpdateApp